﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Owin;

namespace NFinal
{
    using AppFunc = Func<IDictionary<string, object>, Task>;
    public class StaticFileMiddleware
    {
        private readonly AppFunc _next;
        private static string rootDir = null;
        public StaticFileMiddleware(AppFunc next)
        {
            this._next = next;
        }
        /// <summary>
        /// 静态页提供示例，未做任何缓存和304响应处理，仅演示用。
        /// </summary>
        public Task Invoke(IDictionary<string, object> environment)
        {
            IOwinContext context = new OwinContext(environment);
            if (context.Request.Method == "GET" && context.Request.Path.HasValue)
            {
                string path = NFinal.Utility.MapPath(context.Request.Path.Value);
                FileInfo fi = new FileInfo(path);
                var response = context.Response;
                if (fi.Exists)
                {
                    bool isCompress = false;
                    response.ContentType =  NFinal.MimeTypes.GetMimeType(fi.Extension,out isCompress);
                    response.ContentLength = fi.Length;
                    response.StatusCode = 200;
                    if (isCompress)
                    {
                        response.Headers.Add("Content-Encoding",new string[] { "gzip" });
                    }
                    using (FileStream fs = fi.OpenRead())
                    {
                        fs.CopyTo(response.Body);
                    }
                    return _next.Invoke(environment);
                }
                else
                {
                    return FromResult<int>(0);
                }
            }
            else
            {
                return FromResult<int>(0);
            }   
        }
        public static Task<TResult> FromResult<TResult>(TResult resultValue)
        {
            var completionSource = new TaskCompletionSource<TResult>();
            completionSource.SetResult(resultValue);
            return completionSource.Task;
        }
    }
}